<template>
    <div class="project">
        <!-- 体测项目 -->
        <swiper v-if="system" @swiper="onSwiper" @slideChange="onSlideChange"
            :modules="[Navigation, Pagination, Autoplay]" :loop="false" :pagination="{ clickable: true }" navigation
            class="mySwiper">
            <swiper-slide v-if="system == 1 || system == 0" :data-id="9">
                <!--立定跳远  -->
                <LongJump ref="longJumpRef" @start="start" @scanface="scanface" />
            </swiper-slide>
            <swiper-slide v-if="system == 1 || system == 0" :data-id="6">
                <!-- 跳绳 -->
                <RopeSkipping ref="ropeSkippingRef" @start="start" @scanface="scanface" />
            </swiper-slide>
            <swiper-slide v-if="system == 2 || system == 0" :data-id="2">
                <!-- 50男女短跑-->
                <Running :type="50" ref="running50Ref" @start="start" @scanface="scanface" />
            </swiper-slide>
            
            <swiper-slide v-if="system == 3 || system == 0" :data-id="12">
                <!-- 1000男长跑 -->
                <LongRunning :type="1000" ref="longRunning1000Ref" @start="start" @scanface="scanface" />
            </swiper-slide>
            <swiper-slide v-if="system == 3 || system == 0" :data-id="13">
                <!-- 800女长跑 -->
                <LongRunning :type="800" ref="longRunning800Ref" @start="start" @scanface="scanface" />
            </swiper-slide>
        </swiper>

    </div>
    <!-- 项目遮罩开始   -->
    <Teleport to="body" v-if="showModal">
        <div class="modal">
            <div class="modal-btn" @click="startProject">开始</div>
            <img class="modal-close" src="@/assets/images/close.png" @click="closeModal" />
            <img class="modal-left" v-if="isBeginning" @click="prevProject" src="@/assets/images/left-arrow.png" />
            <img class="modal-right" v-if="isEnd" @click="nextProject" src="@/assets/images/right-arrow.png" />
        </div>
    </Teleport>
</template>

<script setup name="Project">
import { ref, computed, onMounted, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
import { Swiper, SwiperSlide } from 'swiper/vue';
import { Navigation, Pagination, Autoplay } from 'swiper/modules';
import LongJump from "./components/LongJump.vue";
import RopeSkipping from "./components/RopeSkipping.vue";
import Running from "./components/Running.vue";
import LongRunning from "./components/LongRunning.vue";
import useUserStore from '@/store/modules/user'
import { connectMQTT, subscribe, publish, onMessage, disconnect } from "@/utils/mqtt.js";
import axios from "axios";
import { getEquipment } from '@/api/tc/equipment'
import { getStudentInfo, getClassList } from "@/api/tc/student.js";
const userStore = useUserStore();
const { proxy } = getCurrentInstance();
const router = useRouter();
const system = ref(null);//0全部   1体测  2短跑  3长跑
const projectId = ref(0); //项目id
const classList = ref([]);//班级列表 用来当做字典id对应的名称
let planId = router.currentRoute.value.query.planId;//考试计划id
let last = 0;//记录上一次项目id
let test = import.meta.env.VITE_APP_TEST;//测试1  正是0
const isScanface = ref(false);//是否开接收人脸消息
const showModal = ref(false);//是否显示遮罩
const swiperRef = ref(null)
const isBeginning = ref(false)
const isEnd = ref(false);
const equipmentList = ref([]);//设备列表
const online = ref(false);//设备是否在线
const screen = ref(null);//当前屏配置信息
let scoreList = [];//保存当前mqttt topic项目成绩
let startEquipment;//开始点设置
// 获取 swiper 实例
// const onSwiper = (swiper) => {
//     swiperRef.value = swiper;
//     // 初始化判断左右箭头是否显示
//     isBeginning.value = !swiper.isBeginning;
//     isEnd.value = !swiper.isEnd;
// }
function timeout() {
    //模拟测试用
    setTimeout(() => {
        //模拟测试发送人脸信息
        publish("tcxt/face_recognition/" + startEquipment.sbClientid, JSON.stringify({ "xsSfz": "74512457854521", pd: 2, }))
        setTimeout(() => {
            publish("tcxt/face_recognition/" + startEquipment.sbClientid, JSON.stringify({ "xsSfz": "01239", pd: 3 }))
        }, 1000)
        setTimeout(() => {
            publish("tcxt/face_recognition/" + startEquipment.sbClientid, JSON.stringify({ "xsSfz": "96369536569", pd: 4 }))
        }, 2000)
        setTimeout(() => {
            publish("tcxt/face_recognition/" + startEquipment.value.sbClientid, JSON.stringify({ "xsSfz": "231085", pd: 1 }))
        }, 2500)
    }, 4000)
}

let timer = null;
onMounted(async () => {
    //获取当前屏幕配置信息
    let data = localStorage.getItem("screen");
    if (data) {
        screen.value = JSON.parse(data);
        //设置屏的类型
        system.value = screen.value.screenType;
        initProjectId();
        await getEquipmentData();
        getStudentClass();
        startMqtt();
    } else {
        proxy.$modal.msgError("未获取到硬件屏幕信息");
    }
    //定时获取设备信息
    timer = setInterval(async () => {
        await getEquipmentData();
    }, 10000)
});

//获取设备信息
async function getEquipmentData() {
    try {
        if (online.value) {
            return;
        }
        if (screen.value == null || screen.value.deviceId == 0) {
            proxy.$modal.msgError("未配置屏类型");
            return;
        }
        equipmentList.value = [];
        //遍历获取设备信息
        for (const item of screen.value.deviceId) {
            const res = await getEquipment({ id: item });
            if (res.rows.length) {
                equipmentList.value.push(res.rows[0])
            }
        }

        //开始点设备
        startEquipment = equipmentList.value.find(f => f.sbOrder == 1);
        //设置设备在线状态
        let temp = online.value;//临时状态
        online.value = true;
        if (online.value) {
            if (temp == false) {
                scanface();
            }
            proxy.$modal.closeLoading();
        } else {
            proxy.$modal.loading("设备离线，请检查设备");
        }

    } catch (err) {
        console.log(err)
    }
}


// function prevProject() {
//     swiperRef.value?.slidePrev()
// }

// function nextProject() {
//     swiperRef.value?.slideNext()
// }

function closeModal() {
    showModal.value = false;
    router.go(-1);
}


/**
 * 开始
 */
function startProject() {
    showModal.value = false;
    scanface();
    if (test == '1') {
        timeout();
    }
}

/**
 * 开始扫描人脸 获取学生信息
 */
async function scanface() {
    try {

        if (test == '0') {
            let formData = {
                'projectId': projectId.value
            }
            if (planId) {
                formData['planId'] = planId;
            }

            //一圈多少米
            if (projectId.value == 13 || projectId.value == 12) {
                formData['pdc'] = 400;
            }
            //让设备开始识别学生
            if (startEquipment) {
                const res = await axios.post(`http://${startEquipment.sbIp2}:8000/startFaceRecognition`, formData, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } })
                console.log('响应数据：', res.data);
            } else {
                proxy.$modal.msgError("人脸识别失败，找不到起开始点设备");
            }
        } else {
            timeout();
        }
        //标识qtt接收人脸信息 防止接受到其他的人脸信息
        isScanface.value = true;
        if (online.value) {
            proxy.$modal.msgSuccess("举手识别");
        }
    } catch (error) {
        proxy.$modal.msgError("人脸识别失败，请检查设备是否在线");
    }
}

/**
 * 开始测试
 */
async function start() {
    try {
        proxy.$modal.loading();
        if (test == '1') {
            //模拟假数据xsSfz
            if (projectId.value != 13) {
                setTimeout(() => {
                    publish("tcxt/sendTcResult/" + startEquipment.sbClientid, JSON.stringify({ "sjSfz": "74512457854521", "sjDfsz": 7.99, "sjFs": 90 }))
                }, 4000)
                setTimeout(() => {
                    publish("tcxt/sendTcResult/" + startEquipment.sbClientid, JSON.stringify({ "sjSfz": "01239", "sjDfsz": 7.1, "sjFs": 95 }))
                }, 5000)

                setTimeout(() => {
                    publish("tcxt/sendTcResult/" + startEquipment.sbClientid, JSON.stringify({ "sjSfz": "96369536569", "sjDfsz": 6.6, "sjFs": 98 }))
                }, 6000)
                setTimeout(() => {
                    publish("tcxt/sendTcResult/" + startEquipment.sbClientid, JSON.stringify({ "sjSfz": "231085", "sjDfsz": 6.3, "sjFs": 100 }))
                }, 7000)
            } else {
                setTimeout(() => {
                    publish("tcxt/sendTcResult/" + startEquipment.sbClientid, JSON.stringify({ "sjSfz": "74512457854521", "sjDfsz": 7.99, projectStatus: 1, roundCount: 1 }))
                }, 4000)
                setTimeout(() => {
                    publish("tcxt/sendTcResult/" + startEquipment.sbClientid, JSON.stringify({ "sjSfz": "74512457854521", "sjDfsz": 15.22, "sjFs": 90, projectStatus: 1, roundCount: 2 }))
                }, 6000)
                setTimeout(() => {
                    publish("tcxt/sendTcResult/" + startEquipment.sbClientid, JSON.stringify({ "sjSfz": "74512457854521", "sjDfsz": 20.56, "sjFs": 90, projectStatus: 1, roundCount: 3 }))
                }, 8000)
                setTimeout(() => {
                    publish("tcxt/sendTcResult/" + startEquipment.sbClientid, JSON.stringify({ "sjSfz": "74512457854521", "sjDfsz": 30.89, "sjFs": 90, roundCount: 4 }))
                }, 9000)

            }
        } else {
            let formData = {
                projectId: projectId.value,
                ope: 'A', //A开始  B暂停
            };

            if (planId) {
                formData['planId'] = planId;
            }
            //一圈多少米
            if (projectId.value == 13 || projectId.value == 12) {
                formData['pdc'] = 400;
            }
            for (const item of equipmentList.value) {
                //每一个设备都发送开始测试命令
              //  item.sbIp2 = startEquipment.sbIp2;
                const res = await axios.post(`http://${item.sbIp2}:8000/startTest`, formData, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } })
                console.log('响应数据：', res.data);
            }
        }
        proxy.$modal.msgSuccess("开始");
        isScanface.value = false;
        //开始测试
        getProjectRef(projectId.value)?.handleStart();
        proxy.$modal.closeLoading();
    } catch (error) {
        proxy.$modal.msgError("请检查设备是否在线");
        proxy.$modal.closeLoading();

    }
}

/**
 * 默认位第一条数据id
 * system #0全部 1体测 2 短跑 3长跑
 * 9立定跳远 6跳绳 2-50短跑 13-800长跑 12-1000长跑
 */
function initProjectId() {
    switch (system.value) {
        case 0:
            projectId.value = 9;
            break;
        case 1:
            projectId.value = 9;
            break;
        case 2:
            projectId.value = 2;
            break;
        case 3:
            projectId.value = 12;
            break;
    }
}


/**
 * mqtt连接订阅人脸和成绩
 */
async function startMqtt() {
    try {
        //mqtt
        await connectMQTT({
            host: 'ws://' + import.meta.env.VITE_APP_TCSERVER + ':8083/mqtt', // MQTT WebSocket 地址
            clientId: 'tcclients_' + userStore.id + "_" + new Date().getTime(),
            username: "admin",
            password: "123456",
        });
        //订阅人脸识别
        let face = "tcxt/face_recognition/" + startEquipment.sbClientid;
        subscribe(face);
        equipmentList.value.forEach(item => {
            //订阅所有设备成绩
            let score = "tcxt/sendTcResult/" + item.sbClientid;
            scoreList.push(score)
            subscribe(score);
        })


        //接收消息
        onMessage(async (topic, msg) => {
            if (msg) {
                //转为对象
                let data = JSON.parse(msg);
                console.log("🚀 ~ data:", data)
                console.log("🚀 ~ topic:", topic)
                //人脸
                if (topic == face && isScanface.value) {
                    //根据身份证号查学生详情数据
                    if (data.id == null || data.id == projectId.value) {
                        await getStudent(data);
                    }
                }     
                //成绩
                if (scoreList.find(f => f == topic)) {
                    //根据身份证号查学生详情数据
                    upodateAhievements(data)
                }
            }
        });
    } catch (err) {
        console.error("MQTT 连接失败:", err);
    }

}

/**
 * 获取学生信息
 */
async function getStudent(data) {
    try {
        let res = await getStudentInfo({ xsSfz: data.xsSfz });
        console.log("🚀 ~ res:", res)
        if (res.rows.length) {
            //获取年级
            // 班级名称
            res.rows[0]['bjName'] = classList.value.find(i => i.id == res.rows[0].xsClassj).bjName;
            //pd跑道位置
            res.rows[0]['pd'] = data?.pd;
            upodateUser(res.rows[0])
        }
    } catch (err) {
        console.log(err)
    }
}

//获取班级
async function getStudentClass() {
    try {
        const res = await getClassList({
            // bjXxid: userStore.deptId,
            pageNum: 1,
            pageSize: 500
        });
        classList.value = res.rows;
    } catch (err) {
        console.log(err)
    }
}

//成绩更新
function upodateAhievements(obj) {
    isScanface.value = false;
    switch (projectId.value) {
        case 9:
            //立定跳远
            proxy.$refs.longJumpRef.ahievements(obj);
            break;
        case 6:
          ///跳绳
            proxy.$refs.ropeSkippingRef.ahievements(obj);
            break;
        case 2:
            //50米
            proxy.$refs.running50Ref.ahievements(obj);
            break;
        case 13:
            //800米
            proxy.$refs.longRunning800Ref.ahievements(obj);
            break;
        case 12:
            ////1000米
            proxy.$refs.longRunning1000Ref.ahievements(obj);
            break;
        default:
            break;
    }
}

//更新学生信息
function upodateUser(obj) {
    if (last != projectId.value) {
        getProjectRef(last)?.resetData();
    }

    switch (projectId.value) {
        case 9:
            //立定跳远
            proxy.$refs.longJumpRef.init(obj);
            isScanface.value = false;
            break;
        case 6:
            ///跳绳
            console.log("跳绳")
            proxy.$refs.ropeSkippingRef.init(obj);
            break;
        case 2:
            //50米
            proxy.$refs.running50Ref.init(obj);
            break;
        case 13:
            //800米
            proxy.$refs.longRunning800Ref.init(obj);
            break;
        case 12:
            //1000米
            proxy.$refs.longRunning1000Ref.init(obj);
            break;
        default:
            break;
    }
    last = projectId.value;
}

/**
 * 根据下标获取组件引用
 * @param index 
 */

function getProjectRef(index) {
    switch (index) {
        case 9:
            return proxy.$refs.longJumpRef;
        case 6:
            return proxy.$refs.ropeSkippingRef;
        case 2:
            return proxy.$refs.running50Ref;
        case 13:
            return proxy.$refs.longRunning800Ref;
        case 12:
            return proxy.$refs.longRunning1000Ref;
        default:
    }
}
/**
 * 
 * @param e 滑动事件
 */
function onSlideChange(e) {
    const el = e.slides[e.activeIndex]
    const id = el.dataset.id;
    // isBeginning.value = !swiperRef.value.isBeginning;
    // isEnd.value = !swiperRef.value.isEnd;
    projectId.value = parseInt(id);
    scanface();
    // showModal.value = true;

}

onBeforeUnmount(() => {
    //关闭mqtt
    disconnect();
});

onUnmounted(() => {
    //清除定时间
    if (timer) {
        clearInterval(timer);
        timer = null;
    }
})


</script>

<style scoped lang="scss">
.project {
    width: 100%;
    height: 100%;
    background: url("@/assets/images/project-bg.png") no-repeat;
    background-size: 100% 100%;
    display: flex;
    overflow: hidden;
}

.modal {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 9999;
    width: 100%;
    height: 100%;
    background-color: rgba($color: #000000, $alpha: 0.6);
    display: flex;
    justify-content: center;
    align-items: center;
    color: #fff;
    font-size: 100px;
    font-weight: bold;

    &-btn {
        cursor: pointer;
        background: #409eff;
        border-radius: 10px;
        padding: 10px 50px;

        &:active {
            opacity: 0.7;
        }
    }

    &-left {
        position: absolute;
        left: 40px;
        top: 46%;
        cursor: pointer;

        &:active {
            opacity: 0.7;
        }
    }

    &-right {
        position: absolute;
        right: 40px;
        top: 46%;
        cursor: pointer;

        &:active {
            opacity: 0.7;
        }
    }

    &-close {
        position: absolute;
        right: 40px;
        top: 40px;
        cursor: pointer;
    }
}
</style>
